import { createClient, SupabaseClient } from '@supabase/supabase-js';
import winston from 'winston';
import cron from 'node-cron';
import { EmailService } from './EmailService';
import { EmailPreferenceService } from './EmailPreferenceService';
import { v4 as uuidv4 } from 'uuid';

export interface ScheduledJob {
  jobId: string;
  jobType: 'daily_digest' | 'weekly_summary' | 'paper_alert' | 'welcome_series' | 'custom';
  schedule: string; // Cron expression
  timezone: string;
  isActive: boolean;
  lastRun?: Date;
  nextRun?: Date;
  metadata: {
    targetUsers?: string[];
    templateType: string;
    parameters?: Record<string, any>;
  };
}

export interface EmailScheduleSettings {
  enabled: boolean;
  dailyDigest: {
    enabled: boolean;
    time: string; // HH:MM format
    timezone: string;
    daysOfWeek: number[]; // 0=Sunday, 1=Monday, etc.
  };
  weeklyDigest: {
    enabled: boolean;
    dayOfWeek: number;
    time: string;
    timezone: string;
  };
  paperAlerts: {
    enabled: boolean;
    immediateThreshold: number; // Relevance score threshold for immediate alerts
    batchInterval: number; // Minutes between batch checks
  };
  welcomeSeries: {
    enabled: boolean;
    delays: number[]; // Days after signup for each welcome email
  };
}

export interface UserSchedule {
  userId: string;
  timezone: string;
  preferences: {
    dailyTime?: string;
    weeklyDay?: number;
    weeklyTime?: string;
    quietHours?: {
      start: string;
      end: string;
    };
  };
  nextScheduledEmails: Array<{
    type: string;
    scheduledFor: Date;
    jobId: string;
  }>;
}

export class EmailSchedulerService {
  private supabase: SupabaseClient;
  private logger: winston.Logger;
  private emailService: EmailService;
  private preferenceService: EmailPreferenceService;
  private activeJobs: Map<string, cron.ScheduledTask> = new Map();
  private isRunning: boolean = false;
  private scheduleSettings: EmailScheduleSettings;

  constructor(
    supabaseUrl: string,
    supabaseKey: string,
    logger: winston.Logger,
    emailService: EmailService,
    preferenceService: EmailPreferenceService,
    settings?: Partial<EmailScheduleSettings>
  ) {
    this.supabase = createClient(supabaseUrl, supabaseKey);
    this.logger = logger;
    this.emailService = emailService;
    this.preferenceService = preferenceService;
    
    this.scheduleSettings = {
      enabled: true,
      dailyDigest: {
        enabled: true,
        time: '09:00',
        timezone: 'UTC',
        daysOfWeek: [1, 2, 3, 4, 5] // Monday to Friday
      },
      weeklyDigest: {
        enabled: true,
        dayOfWeek: 1, // Monday
        time: '10:00',
        timezone: 'UTC'
      },
      paperAlerts: {
        enabled: true,
        immediateThreshold: 0.9,
        batchInterval: 30 // 30 minutes
      },
      welcomeSeries: {
        enabled: true,
        delays: [0, 2, 7] // Welcome emails at signup, 2 days, and 1 week
      },
      ...settings
    };
  }

  /**
   * Start the email scheduler
   */
  async start(): Promise<void> {
    if (this.isRunning) {
      this.logger.warn('Email scheduler is already running');
      return;
    }

    this.logger.info('Starting email scheduler service');
    this.isRunning = true;

    try {
      // Load and start scheduled jobs
      await this.loadScheduledJobs();

      // Start system-level scheduled jobs
      await this.startSystemJobs();

      // Start monitoring for new users (welcome series)
      await this.startWelcomeSeriesMonitor();

      // Start paper alert monitoring
      await this.startPaperAlertMonitor();

      this.logger.info('Email scheduler service started successfully');
    } catch (error) {
      this.logger.error('Failed to start email scheduler:', error);
      this.isRunning = false;
      throw error;
    }
  }

  /**
   * Stop the email scheduler
   */
  async stop(): Promise<void> {
    if (!this.isRunning) {
      this.logger.warn('Email scheduler is not running');
      return;
    }

    this.logger.info('Stopping email scheduler service');

    // Stop all active cron jobs
    for (const [jobId, task] of this.activeJobs) {
      task.destroy();
      this.logger.info(`Stopped scheduled job: ${jobId}`);
    }

    this.activeJobs.clear();
    this.isRunning = false;

    this.logger.info('Email scheduler service stopped');
  }

  /**
   * Schedule daily digest for all eligible users
   */
  async scheduleDailyDigests(): Promise<{ scheduled: number; errors: number }> {
    if (!this.scheduleSettings.dailyDigest.enabled) {
      return { scheduled: 0, errors: 0 };
    }

    this.logger.info('Scheduling daily digests for all eligible users');

    try {
      // Get all users with daily digest preferences
      const { data: users, error } = await this.supabase
        .from('users')
        .select(`
          user_id,
          email,
          timezone,
          notification_preferences!inner(is_enabled)
        `)
        .eq('is_active', true)
        .eq('notification_preferences.notification_type', 'daily_digest')
        .eq('notification_preferences.delivery_method', 'email')
        .eq('notification_preferences.is_enabled', true);

      if (error) {
        throw error;
      }

      let scheduled = 0;
      let errors = 0;

      // Group users by timezone for batch processing
      const usersByTimezone = this.groupUsersByTimezone(users || []);

      for (const [timezone, timezoneUsers] of usersByTimezone.entries()) {
        try {
          // Check if it's the right time to send for this timezone
          if (this.shouldSendDailyDigest(timezone)) {
            // Filter out users in quiet hours
            const eligibleUsers = await this.filterUsersInQuietHours(timezoneUsers, timezone);

            // Schedule digests for eligible users
            for (const user of eligibleUsers) {
              try {
                const digestId = await this.scheduleUserDigest(user.user_id, 'daily_digest');
                if (digestId) {
                  scheduled++;
                }
              } catch (error) {
                this.logger.error(`Failed to schedule daily digest for user ${user.user_id}:`, error);
                errors++;
              }
            }
          }
        } catch (error) {
          this.logger.error(`Failed to process users in timezone ${timezone}:`, error);
          errors += timezoneUsers.length;
        }
      }

      this.logger.info(`Daily digest scheduling completed: ${scheduled} scheduled, ${errors} errors`);
      return { scheduled, errors };

    } catch (error) {
      this.logger.error('Failed to schedule daily digests:', error);
      return { scheduled: 0, errors: 1 };
    }
  }

  /**
   * Schedule weekly summary for all eligible users
   */
  async scheduleWeeklySummaries(): Promise<{ scheduled: number; errors: number }> {
    if (!this.scheduleSettings.weeklyDigest.enabled) {
      return { scheduled: 0, errors: 0 };
    }

    this.logger.info('Scheduling weekly summaries for all eligible users');

    try {
      const { data: users, error } = await this.supabase
        .from('users')
        .select(`
          user_id,
          email,
          timezone,
          notification_preferences!inner(is_enabled)
        `)
        .eq('is_active', true)
        .eq('notification_preferences.notification_type', 'weekly_summary')
        .eq('notification_preferences.delivery_method', 'email')
        .eq('notification_preferences.is_enabled', true);

      if (error) {
        throw error;
      }

      let scheduled = 0;
      let errors = 0;

      const usersByTimezone = this.groupUsersByTimezone(users || []);

      for (const [timezone, timezoneUsers] of usersByTimezone.entries()) {
        try {
          if (this.shouldSendWeeklyDigest(timezone)) {
            const eligibleUsers = await this.filterUsersInQuietHours(timezoneUsers, timezone);

            for (const user of eligibleUsers) {
              try {
                const digestId = await this.scheduleUserDigest(user.user_id, 'weekly_summary');
                if (digestId) {
                  scheduled++;
                }
              } catch (error) {
                this.logger.error(`Failed to schedule weekly summary for user ${user.user_id}:`, error);
                errors++;
              }
            }
          }
        } catch (error) {
          this.logger.error(`Failed to process weekly summaries for timezone ${timezone}:`, error);
          errors += timezoneUsers.length;
        }
      }

      this.logger.info(`Weekly summary scheduling completed: ${scheduled} scheduled, ${errors} errors`);
      return { scheduled, errors };

    } catch (error) {
      this.logger.error('Failed to schedule weekly summaries:', error);
      return { scheduled: 0, errors: 1 };
    }
  }

  /**
   * Schedule individual user digest
   */
  private async scheduleUserDigest(
    userId: string,
    digestType: 'daily_digest' | 'weekly_summary' | 'paper_alert'
  ): Promise<string | null> {
    try {
      // Check if digest was already sent today/this week
      const existingDigest = await this.checkExistingDigest(userId, digestType);
      if (existingDigest) {
        return null; // Already sent
      }

      // Create digest record
      const digestId = uuidv4();
      const { error } = await this.supabase
        .from('email_digests')
        .insert({
          digest_id: digestId,
          user_id: userId,
          digest_type: digestType,
          digest_date: new Date().toISOString().split('T')[0],
          subject_line: this.generateSubjectLine(digestType),
          generation_time: new Date().toISOString(),
          is_sent: false,
          delivery_status: 'pending'
        });

      if (error) {
        throw error;
      }

      // Add to background job queue for actual email generation and sending
      await this.queueDigestJob(digestId, userId, digestType);

      return digestId;
    } catch (error) {
      this.logger.error(`Failed to schedule digest for user ${userId}:`, error);
      return null;
    }
  }

  /**
   * Start welcome series for new user
   */
  async startWelcomeSeriesForUser(userId: string): Promise<void> {
    if (!this.scheduleSettings.welcomeSeries.enabled) {
      return;
    }

    try {
      const user = await this.getUserInfo(userId);
      if (!user) {
        throw new Error(`User not found: ${userId}`);
      }

      // Check if user has welcome series enabled
      const preferences = await this.preferenceService.getUserPreferences(userId);
      if (!preferences?.digestTypes.welcomeSeries) {
        return;
      }

      // Schedule each welcome email
      for (let i = 0; i < this.scheduleSettings.welcomeSeries.delays.length; i++) {
        const delayDays = this.scheduleSettings.welcomeSeries.delays[i];
        const scheduledTime = new Date();
        scheduledTime.setDate(scheduledTime.getDate() + delayDays);

        // For immediate emails (delay 0), send right away but respect quiet hours
        if (delayDays === 0) {
          scheduledTime.setMinutes(scheduledTime.getMinutes() + 5); // 5 minute delay
        } else {
          // Schedule for optimal time in user's timezone
          scheduledTime.setHours(10, 0, 0, 0); // 10 AM in user's timezone
        }

        await this.scheduleWelcomeEmail(userId, i + 1, scheduledTime);
      }

      this.logger.info(`Welcome series scheduled for user: ${userId}`);
    } catch (error) {
      this.logger.error(`Failed to start welcome series for user ${userId}:`, error);
    }
  }

  /**
   * Check for high-relevance papers and send immediate alerts
   */
  async checkPaperAlerts(): Promise<{ alerts: number; errors: number }> {
    if (!this.scheduleSettings.paperAlerts.enabled) {
      return { alerts: 0, errors: 0 };
    }

    try {
      // Get recent high-relevance recommendations
      const { data: recommendations, error } = await this.supabase
        .from('user_recommendations')
        .select(`
          user_id,
          paper_id,
          recommendation_score,
          generated_at,
          papers (*)
        `)
        .gte('recommendation_score', this.scheduleSettings.paperAlerts.immediateThreshold)
        .gte('generated_at', new Date(Date.now() - 2 * 60 * 60 * 1000).toISOString()) // Last 2 hours
        .eq('is_clicked', false);

      if (error) {
        throw error;
      }

      let alerts = 0;
      let errors = 0;

      // Group by user
      const userRecommendations = new Map<string, any[]>();
      recommendations?.forEach(rec => {
        if (!userRecommendations.has(rec.user_id)) {
          userRecommendations.set(rec.user_id, []);
        }
        userRecommendations.get(rec.user_id)!.push(rec);
      });

      // Send alerts for each user
      for (const [userId, userRecs] of userRecommendations) {
        try {
          // Check if user has paper alerts enabled
          const preferences = await this.preferenceService.getUserPreferences(userId);
          if (!preferences?.digestTypes.paperAlerts) {
            continue;
          }

          // Check if user is in quiet hours
          if (await this.isUserInQuietHours(userId, preferences.quietHours)) {
            // Schedule for later
            await this.scheduleDelayedAlert(userId, userRecs);
            continue;
          }

          // Send immediate alert for the highest scoring paper
          const topPaper = userRecs.sort((a, b) => b.recommendation_score - a.recommendation_score)[0];
          
          const result = await this.emailService.sendPersonalizedEmail(
            userId,
            'paper_alert',
            {
              papers: [topPaper.papers],
              alertReason: `High relevance match (${Math.round(topPaper.recommendation_score * 100)}%)`
            }
          );

          if (result.success) {
            alerts++;
            // Mark recommendation as processed
            await this.supabase
              .from('user_recommendations')
              .update({ is_clicked: true })
              .eq('user_id', userId)
              .eq('paper_id', topPaper.paper_id);
          } else {
            errors++;
          }

        } catch (error) {
          this.logger.error(`Failed to send paper alert to user ${userId}:`, error);
          errors++;
        }
      }

      this.logger.info(`Paper alerts completed: ${alerts} sent, ${errors} errors`);
      return { alerts, errors };

    } catch (error) {
      this.logger.error('Failed to check paper alerts:', error);
      return { alerts: 0, errors: 1 };
    }
  }

  /**
   * Get user's scheduled emails
   */
  async getUserSchedule(userId: string): Promise<UserSchedule | null> {
    try {
      const user = await this.getUserInfo(userId);
      if (!user) return null;

      const preferences = await this.preferenceService.getUserPreferences(userId);
      if (!preferences) return null;

      // Get upcoming scheduled emails
      const { data: upcomingDigests } = await this.supabase
        .from('email_digests')
        .select('digest_type, digest_date')
        .eq('user_id', userId)
        .eq('is_sent', false)
        .gte('digest_date', new Date().toISOString().split('T')[0])
        .order('digest_date', { ascending: true })
        .limit(10);

      const nextScheduledEmails = upcomingDigests?.map(digest => ({
        type: digest.digest_type,
        scheduledFor: new Date(digest.digest_date),
        jobId: `${digest.digest_type}_${digest.digest_date}`
      })) || [];

      return {
        userId,
        timezone: user.timezone || 'UTC',
        preferences: {
          dailyTime: preferences.deliverySettings ? '09:00' : undefined, // This would come from user prefs
          weeklyDay: 1, // Monday
          weeklyTime: '10:00',
          quietHours: preferences.quietHours.enabled ? {
            start: preferences.quietHours.start,
            end: preferences.quietHours.end
          } : undefined
        },
        nextScheduledEmails
      };

    } catch (error) {
      this.logger.error(`Failed to get user schedule for ${userId}:`, error);
      return null;
    }
  }

  /**
   * Update user's email schedule
   */
  async updateUserSchedule(
    userId: string,
    schedule: Partial<UserSchedule['preferences']>
  ): Promise<{ success: boolean; error?: string }> {
    try {
      const preferences = await this.preferenceService.getUserPreferences(userId);
      if (!preferences) {
        return { success: false, error: 'User preferences not found' };
      }

      // Update relevant preferences
      const updatePrefs: any = {};

      if (schedule.dailyTime) {
        updatePrefs.dailyEmailTime = schedule.dailyTime;
      }

      if (schedule.weeklyDay !== undefined) {
        updatePrefs.weeklyEmailDay = schedule.weeklyDay;
      }

      if (schedule.weeklyTime) {
        updatePrefs.weeklyEmailTime = schedule.weeklyTime;
      }

      if (schedule.quietHours) {
        updatePrefs.quietHours = {
          ...preferences.quietHours,
          enabled: true,
          start: schedule.quietHours.start,
          end: schedule.quietHours.end
        };
      }

      const result = await this.preferenceService.updateUserPreferences(userId, updatePrefs);
      
      if (result.success) {
        this.logger.info(`User schedule updated: ${userId}`);
      }

      return result;
    } catch (error) {
      this.logger.error(`Failed to update user schedule for ${userId}:`, error);
      return { success: false, error: error instanceof Error ? error.message : 'Unknown error' };
    }
  }

  /**
   * Private helper methods
   */
  private async loadScheduledJobs(): Promise<void> {
    // Load any persisted scheduled jobs from database
    const { data: jobs } = await this.supabase
      .from('background_jobs')
      .select('*')
      .eq('job_type', 'email_schedule')
      .eq('job_status', 'pending');

    jobs?.forEach(job => {
      // Recreate cron jobs from database records
      this.logger.info(`Loading scheduled job: ${job.job_id}`);
    });
  }

  private async startSystemJobs(): Promise<void> {
    // Daily digest job - runs every hour to check for users in different timezones
    const dailyJob = cron.schedule('0 * * * *', async () => {
      if (this.scheduleSettings.dailyDigest.enabled) {
        await this.scheduleDailyDigests();
      }
    }, {
      scheduled: false,
      timezone: 'UTC'
    });

    // Weekly digest job - runs every Monday at various hours for different timezones  
    const weeklyJob = cron.schedule('0 8-20 * * 1', async () => {
      if (this.scheduleSettings.weeklyDigest.enabled) {
        await this.scheduleWeeklySummaries();
      }
    }, {
      scheduled: false,
      timezone: 'UTC'
    });

    // Paper alert job - runs every 30 minutes
    const alertJob = cron.schedule(`*/${this.scheduleSettings.paperAlerts.batchInterval} * * * *`, async () => {
      if (this.scheduleSettings.paperAlerts.enabled) {
        await this.checkPaperAlerts();
      }
    }, {
      scheduled: false,
      timezone: 'UTC'
    });

    dailyJob.start();
    weeklyJob.start();
    alertJob.start();

    this.activeJobs.set('daily_digest_system', dailyJob);
    this.activeJobs.set('weekly_digest_system', weeklyJob);
    this.activeJobs.set('paper_alerts_system', alertJob);
  }

  private async startWelcomeSeriesMonitor(): Promise<void> {
    // Monitor for new user registrations every 5 minutes
    const welcomeJob = cron.schedule('*/5 * * * *', async () => {
      if (this.scheduleSettings.welcomeSeries.enabled) {
        // Get users registered in the last 5 minutes
        const fiveMinutesAgo = new Date(Date.now() - 5 * 60 * 1000);
        
        const { data: newUsers } = await this.supabase
          .from('users')
          .select('user_id, created_at')
          .gte('created_at', fiveMinutesAgo.toISOString())
          .eq('is_active', true);

        for (const user of newUsers || []) {
          await this.startWelcomeSeriesForUser(user.user_id);
        }
      }
    }, {
      scheduled: false,
      timezone: 'UTC'
    });

    welcomeJob.start();
    this.activeJobs.set('welcome_series_monitor', welcomeJob);
  }

  private async startPaperAlertMonitor(): Promise<void> {
    // Already handled in startSystemJobs as part of paper alert job
  }

  private groupUsersByTimezone(users: any[]): Map<string, any[]> {
    const grouped = new Map<string, any[]>();
    
    users.forEach(user => {
      const timezone = user.timezone || 'UTC';
      if (!grouped.has(timezone)) {
        grouped.set(timezone, []);
      }
      grouped.get(timezone)!.push(user);
    });

    return grouped;
  }

  private shouldSendDailyDigest(timezone: string): boolean {
    const now = new Date();
    const userTime = new Date(now.toLocaleString("en-US", { timeZone: timezone }));
    const hour = userTime.getHours();
    const dayOfWeek = userTime.getDay();

    // Check if it's the right hour (allow 1 hour window around target time)
    const targetHour = parseInt(this.scheduleSettings.dailyDigest.time.split(':')[0]);
    const hourMatch = Math.abs(hour - targetHour) <= 1;

    // Check if it's the right day of week
    const dayMatch = this.scheduleSettings.dailyDigest.daysOfWeek.includes(dayOfWeek);

    return hourMatch && dayMatch;
  }

  private shouldSendWeeklyDigest(timezone: string): boolean {
    const now = new Date();
    const userTime = new Date(now.toLocaleString("en-US", { timeZone: timezone }));
    const hour = userTime.getHours();
    const dayOfWeek = userTime.getDay();

    const targetHour = parseInt(this.scheduleSettings.weeklyDigest.time.split(':')[0]);
    const hourMatch = Math.abs(hour - targetHour) <= 1;
    const dayMatch = dayOfWeek === this.scheduleSettings.weeklyDigest.dayOfWeek;

    return hourMatch && dayMatch;
  }

  private async filterUsersInQuietHours(users: any[], timezone: string): Promise<any[]> {
    const eligibleUsers = [];

    for (const user of users) {
      const preferences = await this.preferenceService.getUserPreferences(user.user_id);
      if (!preferences?.quietHours.enabled || 
          !await this.isUserInQuietHours(user.user_id, preferences.quietHours)) {
        eligibleUsers.push(user);
      }
    }

    return eligibleUsers;
  }

  private async isUserInQuietHours(
    userId: string,
    quietHours: { enabled: boolean; start: string; end: string; timezone: string }
  ): Promise<boolean> {
    if (!quietHours.enabled) return false;

    const now = new Date();
    const userTime = new Date(now.toLocaleString("en-US", { timeZone: quietHours.timezone }));
    const currentHour = userTime.getHours();
    const currentMinute = userTime.getMinutes();
    const currentTime = currentHour * 60 + currentMinute;

    const [startHour, startMin] = quietHours.start.split(':').map(Number);
    const [endHour, endMin] = quietHours.end.split(':').map(Number);
    const startTime = startHour * 60 + startMin;
    const endTime = endHour * 60 + endMin;

    // Handle overnight quiet hours (e.g., 22:00 to 08:00)
    if (startTime > endTime) {
      return currentTime >= startTime || currentTime <= endTime;
    } else {
      return currentTime >= startTime && currentTime <= endTime;
    }
  }

  private async checkExistingDigest(
    userId: string,
    digestType: string
  ): Promise<boolean> {
    const today = new Date().toISOString().split('T')[0];
    let dateFilter = today;

    // For weekly digest, check the entire week
    if (digestType === 'weekly_summary') {
      const weekStart = new Date();
      weekStart.setDate(weekStart.getDate() - weekStart.getDay() + 1); // Monday
      dateFilter = weekStart.toISOString().split('T')[0];
    }

    const { data } = await this.supabase
      .from('email_digests')
      .select('digest_id')
      .eq('user_id', userId)
      .eq('digest_type', digestType)
      .gte('digest_date', dateFilter)
      .limit(1)
      .single();

    return !!data;
  }

  private generateSubjectLine(digestType: string): string {
    const subjects = {
      'daily_digest': '📚 Your Daily ArXiv Digest',
      'weekly_summary': '📊 Weekly Research Roundup',
      'paper_alert': '🔔 New Paper Alert'
    };
    return subjects[digestType as keyof typeof subjects] || 'ArXiv Update';
  }

  private async queueDigestJob(digestId: string, userId: string, digestType: string): Promise<void> {
    // Add to background job queue
    await this.supabase
      .from('background_jobs')
      .insert({
        job_type: 'email_digest_generation',
        job_data: {
          digestId,
          userId,
          digestType
        },
        scheduled_at: new Date().toISOString(),
        job_status: 'pending'
      });
  }

  private async scheduleWelcomeEmail(userId: string, step: number, scheduledTime: Date): Promise<void> {
    const digestId = uuidv4();
    
    await this.supabase
      .from('email_digests')
      .insert({
        digest_id: digestId,
        user_id: userId,
        digest_type: 'welcome_series',
        digest_date: scheduledTime.toISOString().split('T')[0],
        subject_line: `Welcome to ArXiv Research Hub - Step ${step}`,
        generation_time: new Date().toISOString(),
        is_sent: false,
        delivery_status: 'scheduled'
      });

    // Schedule the actual sending
    await this.supabase
      .from('background_jobs')
      .insert({
        job_type: 'welcome_email',
        job_data: {
          digestId,
          userId,
          step,
          templateType: `welcome_series_${step}`
        },
        scheduled_at: scheduledTime.toISOString(),
        job_status: 'pending'
      });
  }

  private async scheduleDelayedAlert(userId: string, recommendations: any[]): Promise<void> {
    // Schedule alert for when user's quiet hours end
    const preferences = await this.preferenceService.getUserPreferences(userId);
    if (!preferences) return;

    const quietEnd = preferences.quietHours.end;
    const [hour, minute] = quietEnd.split(':').map(Number);
    
    const scheduledTime = new Date();
    scheduledTime.setHours(hour, minute, 0, 0);
    
    // If the end time is today but has passed, schedule for tomorrow
    if (scheduledTime < new Date()) {
      scheduledTime.setDate(scheduledTime.getDate() + 1);
    }

    const digestId = uuidv4();
    await this.queueDigestJob(digestId, userId, 'paper_alert');
  }

  private async getUserInfo(userId: string): Promise<any> {
    const { data } = await this.supabase
      .from('users')
      .select('email, timezone, is_active')
      .eq('user_id', userId)
      .single();
    
    return data;
  }
}